# coding:utf8
import sys
from time import sleep

from utils import logger_util
import requests
import consul
import yaml
import os

logger = logger_util.get_logger("config")
_config = None
_local_config = None
_server_config = None
# 配置文件的路径会随调用位置不同而变
_pro_conf_file_path = './proCfg.yaml'
_dev_conf_file_path = 'devCfg.yaml'
_docker_conf_file_path = './dockerCfg.yaml'

_max_get_val_retry_time = 3
_get_val_retried_time = 0
_get_val_sleep_time = 3


def _check_conf_file_exist(env):
    # if env == 'pro':
    #     if not os.path.exists(_pro_conf_file_path):
    #         raise FileExistsError('Not {} conf file exist'.format(env))
    # elif env == 'dev':
    #     if not os.path.exists(_dev_conf_file_path):
    #         raise FileExistsError('Not {} conf file exist'.format(env))
    # elif env == 'docker':
    #     if not os.path.exists(_docker_conf_file_path):
    #         raise FileExistsError('Not {} conf file exist'.format(env))
    # else:
    #     raise KeyError('Not this kind of config')

    conf_file_path = f"./config/{env}Cfg.yaml"
    if not os.path.exists(conf_file_path):
        raise FileExistsError(f"Not {conf_file_path} conf file exist")


def get_config():
    global _config
    if not _config:
        _config = {}
        # 配置优先级从上到下递增
        _config.update(get_local_config())
        _config.update(get_server_config())
    return _config


def get_local_config():
    global _local_config
    if not _local_config:
        _local_config = {}
        _local_config.update(get_env_config())
        _local_config.update(get_file_config())
        validate_local_config(_local_config)
    return _local_config


def get_server_config():
    global _server_config
    if not _server_config:
        try:
            _server_config = get_value(get_local_config()["Consul"]["config_name"])
            if _server_config is None:
                _server_config = {}
        except requests.exceptions.ConnectionError:
            logger.info("获取consul配置中心的配置失败")
            _server_config = {}
    return _server_config


def get_env_config():
    _env_config = {}
    _env_config.update({"Consul": {"host": os.getenv("CONSUL_HOST"), "port": os.getenv("CONSUL_PORT"),
                                   "config_name": os.getenv("CONSUL_CONFIG_NAME")}})
    return _env_config


def get_file_config():
    _file_config = {}
    if len(sys.argv) > 1:
        env = sys.argv[1]
        conf_file_path = f"./config/{env}Cfg.yaml"
        f = open(conf_file_path, encoding='utf-8')
        _file_config = yaml.load(f, Loader=yaml.FullLoader)
        if _file_config is None:
            _file_config = {}
    return _file_config


def get_value(key):
    global _get_val_retried_time
    global _max_get_val_retry_time
    global _get_val_sleep_time
    c = consul.Consul(get_local_config()["Consul"]['host'], get_local_config()["Consul"]['port'])
    try:
        value = c.kv.get(key)
    except consul.ConsulException as e:
        _get_val_retried_time += 1
        if _get_val_retried_time > _max_get_val_retry_time:
            raise RuntimeError("获取配置中心配置失败，请检查配置中心网络情况")
       
        logger.info("获取consul配置中心的配置失败,正在尝试")
        sleep(_get_val_sleep_time)
        return get_value(key)

    _get_val_retried_time = 0
    if value[1] is None or value[1]["Value"] is None:
        return None
    return yaml.load(str(value[1]["Value"], "utf-8"), Loader=yaml.FullLoader)


def validate_local_config(_local_config):
    if "Consul" not in _local_config.keys() or _local_config["Consul"] is None:
        raise RuntimeError("缺少Consul配置")
    if "host" not in _local_config["Consul"].keys() or _local_config["Consul"]["host"] is None:
        raise RuntimeError("缺少Consul host配置")
    if "port" not in _local_config["Consul"].keys() or _local_config["Consul"]["port"] is None:
        raise RuntimeError("缺少Consul port配置")
    if "config_name" not in _local_config["Consul"].keys() or _local_config["Consul"]["config_name"] is None:
        raise RuntimeError("缺少Consul config_name配置")
